package com.bbcare.img.plat.controller;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bbcare.comm.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bbcare.img.plat.service.IClientImgDealService;

/**
 * @name: 影像文件上传处理类
 * @author: DemonLee
 * @createTime: 2017.10.30
 * @description: 客户端或网页手动上传影像文件等操作
 * @modify:
 *
 */
@Controller
public class ImgUploadController {
    private final Log logger = LogFactory.getLog(ImgUploadController.class);

    @Autowired
    private IClientImgDealService clientImgDealService;

    // 客户端影像文件上传
    @ResponseBody
    @RequestMapping("/imgClientApi/upload/uploadClientImg")
    public Object uploadMultiFile(HttpServletRequest request) throws Exception {
        logger.info("---in uploadMultiFile---");
        Map<String, Object> retMap = new HashMap<String, Object>();

        // 基础校验
        String arg = request.getParameter("data");
        ToolUtil.checkInputRootNode(arg);

        Map<String, Object> mapIn = JSON.parseObject(arg);

        // 操作信息校验
        Map<String, Object> chkVar = new HashMap<String, Object>();
        Map<String, Object> chkInfo = ToolUtil.typeCast(mapIn.get("oprInfo"));
        chkVar.put("opCode", "操作编码");
        chkVar.put("opType", "操作类型");
        chkVar.put("opNote", "操作备注");
        chkVar.put("programId", "客户端程序编号");
        ToolUtil.checkInputInfo("oprInfo", chkInfo, chkVar);
        chkInfo.put("updateTime", DateUtil.getSysDateA());
        chkInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
        chkInfo.put("uploadType", Constants.FILE_UPLOAD_TYPE_FOR_BACKGROUND_PROGRAM);
        // 设备信息校验
        chkVar.clear();
        chkInfo = ToolUtil.typeCast(mapIn.get("fileInfo"));
        chkVar.put("fileCreateTime", "文件创建时间");
        chkVar.put("fileModifyTime", "文件修改时间");
        chkVar.put("insideIp", "客户端主机内网ip");
        chkVar.put("sourceFilePath", "文件本地存放路径");
        ToolUtil.checkInputInfo("fileInfo", chkInfo, chkVar);
        // 上传文件校验
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                int flag = 1;
                while (iter.hasNext()) {
                    MultipartFile file = multiRequest.getFile(iter.next());
                    // 校验文件扩展名
                    ToolUtil.checkFileSuffix(file.getOriginalFilename());
                    if (file.isEmpty()) {
                        flag = 0;
                        break;
                    }
                }
                if (0 == flag) {
                    throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY, "文件上传失败，上传内容为空!");
                }

                retMap = clientImgDealService.uploadClientImg(mapIn, multiRequest);
            } else {
                throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY, "文件上传失败，上传文件为空!");
            }
        }

        return new ResultModel<Object>(retMap);
    }

    // web端手动上传文件
    @ResponseBody
    @RequestMapping("/upload/uploadWebImg")
    public Object uploadWebImg(HttpServletRequest request) throws Exception {
        Map<String, Object> retMap = new HashMap<String, Object>();

        // 基础校验
        String arg = request.getParameter("data");
        ToolUtil.checkInputRootNode(arg);

        Map<String, Object> mapIn = JSON.parseObject(arg);

        // 操作信息校验
        Map<String, Object> chkVar = new HashMap<String, Object>();
        Map<String, Object> chkInfo = ToolUtil.typeCast(mapIn.get("oprInfo"));
        chkVar.put("opCode", "操作编码");
        chkVar.put("opType", "操作类型");
        chkVar.put("opNote", "操作备注");
        chkVar.put("equipId", "设备id");
        chkVar.put("equipFlag", "设备标志类型");
        ToolUtil.checkInputInfo("oprInfo", chkInfo, chkVar);
        chkInfo.put("updateTime", DateUtil.getSysDateA());
        chkInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
        chkInfo.put("uploadType", Constants.FILE_UPLOAD_TYPE_FOR_MANUAL);
        // 设备信息校验
        chkVar.clear();
        List<Object> fileList = ToolUtil.typeCast(mapIn.get("fileList"));
        chkVar.put("fileCreateTime", "文件创建时间");
        chkVar.put("fileModifyTime", "文件修改时间");
        ToolUtil.checkInputList("fileList", fileList, chkVar);
        // 患者基本信息校验
        chkVar.clear();
        chkInfo = ToolUtil.typeCast(mapIn.get("userInfo"));
        chkVar.put("userId", "患者id");
        chkVar.put("birthday", "出生日期");
        chkVar.put("gender", "性别");
        ToolUtil.checkInputInfo("userInfo", chkInfo, chkVar);
        // 登录信息，从session中获取
        Map<String, Object> sessionMap = ToolUtil.getSessionInfo(request);
        mapIn.put("sessionInfo", sessionMap);
        // 上传文件校验
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                int flag = 1;
                int fileNum = 0;
                while (iter.hasNext()) {
                    MultipartFile file = multiRequest.getFile(iter.next());
                    // 校验文件扩展名
                    ToolUtil.checkFileSuffix(file.getOriginalFilename());
                    if (file.isEmpty()) {
                        flag = 0;
                        break;
                    }
                    fileNum++;
                }
                if (0 == flag) {
                    throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY, "文件上传失败，上传内容为空!");
                }

                logger.info("fileNum==" + fileNum + ", fileList.size()==" + fileList.size());
                if (fileNum != fileList.size()) {
                    // 文件个数与文件入参是否匹配
                    throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY,
                            "文件上传失败，上传文件个数与入参中文件信息List不匹配!");
                }

                retMap = clientImgDealService.uploadMultiClientImg(mapIn, multiRequest);
            } else {
                throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY, "文件上传失败，上传文件为空!");
            }
        }

        return new ResultModel<Object>(retMap);
    }

    // web端手动上传文件
    @ResponseBody
    @RequestMapping("/upload/saveClipImg")
    public Object saveClipImg(HttpServletRequest request) throws Exception {
        Map<String, Object> retMap = new HashMap<String, Object>();

        // 基础校验
        String arg = request.getParameter("data");
        ToolUtil.checkInputRootNode(arg);

        Map<String, Object> mapIn = JSON.parseObject(arg);

        // 操作信息校验
        Map<String, Object> chkVar = new HashMap<String, Object>();
        Map<String, Object> chkInfo = ToolUtil.typeCast(mapIn.get("oprInfo"));
        chkVar.put("opCode", "操作编码");
        chkVar.put("opType", "操作类型");
        chkVar.put("opNote", "操作备注");
        ToolUtil.checkInputInfo("oprInfo", chkInfo, chkVar);
        chkInfo.put("updateTime", DateUtil.getSysDateA());
        chkInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
        chkInfo.put("uploadType", Constants.FILE_UPLOAD_TYPE_FOR_CLIP);
        // 设备信息校验
        chkVar.clear();
        chkInfo = ToolUtil.typeCast(mapIn.get("fileInfo"));
        chkVar.put("imgId", "原文件id");
        ToolUtil.checkInputInfo("fileInfo", chkInfo, chkVar);
        // 患者基本信息校验
        chkVar.clear();
        chkInfo = ToolUtil.typeCast(mapIn.get("userInfo"));
        chkVar.put("userId", "患者id");
        ToolUtil.checkInputInfo("userInfo", chkInfo, chkVar);
        // 登录信息，从session中获取
        Map<String, Object> sessionMap = ToolUtil.getSessionInfo(request);
        mapIn.put("sessionInfo", sessionMap);
        // 上传文件校验
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                int flag = 1;
                while (iter.hasNext()) {
                    MultipartFile file = multiRequest.getFile(iter.next());
                    // 校验文件扩展名
                    ToolUtil.checkFileSuffix(file.getOriginalFilename());
                    if (file.isEmpty()) {
                        flag = 0;
                        break;
                    }
                }
                if (0 == flag) {
                    throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY, "文件上传失败，上传内容为空!");
                }

                retMap = clientImgDealService.uploadClientImg(mapIn, multiRequest);
            } else {
                throw new AppException(ErrorCode.FOLLOW_EXCEPTION_TYPE_UPLOAD_FILE_MPTY, "文件上传失败，上传文件为空!");
            }
        }

        return new ResultModel<Object>(retMap);
    }


    /**
     * 南方医院文件上传
     *
     * @param response
     * @param request
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/uploadFile")
    public ResultModel<Object> uploadFile(HttpServletResponse response, HttpServletRequest request)
            throws Exception {
    	Map<String,Object> mapIn = new HashMap<String,Object>();
    	Map<String,Object> fileInfo = new HashMap<String,Object>();
        String filepath = "";
        //list 上传文件文件信息
        String data = request.getParameter("data");
        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(data);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参错误，非json格式！"));
        }

        JSONObject json = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == json) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参校验失败，无data节点！"));
        }
        //文件信息
        JSONArray jsonData = json.getJSONArray("FileInfo");
        if (null == jsonData) {
            // 文件信息
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参校验失败，没有文件信息！"));
        }

        //用户id
        String userId =json.getString("userId");
        if (null == userId) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参校验失败，没有用户id！"));
        }

        //队列实例id
        String ptSchemeId =json.getString("ptSchemeId");
        if (null == ptSchemeId) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参校验失败，没有队列实例id！"));
        }

        //队列id
        String queueId =json.getString("queueId");
        if (null == queueId) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参校验失败，没有队列id！"));
        }

        String opCode = json.getString("opCode");
        if(StringUtils.isBlank(opCode)) {
        	opCode = "2119";
        }
        String opNote = json.getString("opNote");
        if(StringUtils.isBlank(opNote)) {
        	opNote = "南方医院文件上传";
        }
        String opType = json.getString("opType");
        if(StringUtils.isBlank(opType)) {
        	opType = "2";
        }

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtil.getSessionInfo(request);
        String author = (String) sessionMap.get("authorId");
        // 登录账号医生姓名
        String authorName = (String) sessionMap.get("authorName");
        // 租户id
        String tenantId = (String) sessionMap.get("tenantId");
        mapIn.put("author", author);
        mapIn.put("authorName", authorName);
        mapIn.put("tenantId", tenantId);
        mapIn.put("userId", userId);
        mapIn.put("ptSchemeId", ptSchemeId);
        mapIn.put("queueId", queueId);
        mapIn.put("opCode", opCode);
        mapIn.put("opNote", opNote);
        mapIn.put("opType", opType);
        mapIn.put("updateTime", DateUtil.getSysDateA());
        mapIn.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            int i=0;
            while (iter.hasNext()) {
                MultipartFile file = multiRequest.getFile(iter.next());
                if (!file.isEmpty()) {
                	 // 文件上传路径：基础路径+租户id
                    String  uploadPath = ToolUtil.getUploadFilePath(Constants.FILE_UPLOAD_FOR_IMG_BASIC_PATH_ID_NAME, tenantId);
                    filepath = OSSClientUtil.uploadPicture(file, uploadPath,fileInfo,true);// 保存图片
                    JSONObject jsonArg1 = jsonData.getJSONObject(i);
                    mapIn.put("filePath", filepath);
                    String image = filepath.substring(filepath.lastIndexOf("/")+1);
                    String imagetype = filepath.substring(filepath.lastIndexOf(".")+1);
                    mapIn.put("fileName", image);
                    mapIn.put("filesize", file.getSize());
                    mapIn.put("fileType", imagetype);
                    mapIn.put("fileNameOld", jsonArg1.get("fileName"));
                    mapIn.put("fileCreateTime", jsonArg1.get("fileCreateTime"));
                    mapIn.put("fileModifyTime", jsonArg1.get("fileModifyTime"));
                    clientImgDealService.saveFileInfo(mapIn);
                }
                i++;
            }
            //入业务记录表
            clientImgDealService.saveOpration(mapIn);
        }
        return new ResultModel<Object>(filepath);
    }


	 /**
	  * @author wuyz
	  * @time 2018-04-28
	  * 前端上传文件，将文件信息传入，后端只是入库操作，不做上传文件操作
	  *
	  **/
    @ResponseBody
    @RequestMapping("/upload/saveWebImgInfo")
    public Object saveWebImgInfo(@RequestBody String arg,HttpServletRequest request) throws Exception {
        Map<String, Object> retMap = new HashMap<String, Object>();

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        Map<String, Object> mapIn = jsonData;
        logger.info("saveWebImgInfo :"+mapIn);

        // 操作信息校验
        Map<String, Object> chkVar = new HashMap<String, Object>();
        Map<String, Object> chkInfo = ToolUtil.typeCast(mapIn.get("oprInfo"));
        chkVar.put("opCode", "操作编码");
        chkVar.put("opType", "操作类型");
        chkVar.put("opNote", "操作备注");
        chkVar.put("equipId", "设备id");
        chkVar.put("equipFlag", "设备标志类型");
        ToolUtil.checkInputInfo("oprInfo", chkInfo, chkVar);
        chkInfo.put("updateTime", DateUtil.getSysDateA());
        chkInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
        chkInfo.put("uploadType", Constants.FILE_UPLOAD_TYPE_FOR_MANUAL);
        // 设备信息校验
        chkVar.clear();
        List<Object> fileList = ToolUtil.typeCast(mapIn.get("fileList"));
        chkVar.put("fileCreateTime", "文件创建时间");
        chkVar.put("fileModifyTime", "文件修改时间");
        chkVar.put("sourceFileName", "文件原来名称");
        chkVar.put("fileSize", "文件大小");
        chkVar.put("filePath", "文件保存阿里地址");

        ToolUtil.checkInputList("fileList", fileList, chkVar);
        // 校验文件扩展名
        for(int i=0;i<fileList.size();i++) {
        	//将Object 转成map
        	Map<String,Object> map = ToolUtil.typeCast(fileList.get(i));
        	map.put("fileSize", Long.parseLong((String)map.get("fileSize")));
        	ToolUtil.checkFileSuffix((String)map.get("sourceFileName"));
        	 int pointPos = ((String) map.get("filePath")).lastIndexOf(Constants.SLASH_STR);
             if (-1 != pointPos) {
                String substring = ((String) map.get("filePath")).substring(pointPos + 1);
                map.put("fileName", substring);
             }
             pointPos = ((String) map.get("sourceFileName")).lastIndexOf(Constants.dot);
             if (-1 != pointPos) {
            	 String substring = ((String) map.get("sourceFileName")).substring(pointPos + 1).toLowerCase();
                 map.put("fileType", substring);
             }
        }

        // 患者基本信息校验
        chkVar.clear();
        chkInfo = ToolUtil.typeCast(mapIn.get("userInfo"));
        chkVar.put("userId", "患者id");
        chkVar.put("birthday", "出生日期");
        chkVar.put("gender", "性别");
        ToolUtil.checkInputInfo("userInfo", chkInfo, chkVar);
        // 登录信息，从session中获取
        Map<String, Object> sessionMap = ToolUtil.getSessionInfo(request);
        mapIn.put("sessionInfo", sessionMap);

        retMap = clientImgDealService.saveWebImgInfo(mapIn);

        return new ResultModel<Object>(retMap);
    }


    /**
	  * @author wuyz
	  * @time 2018-07-24
	  * 前端上传文件，将文件信息传入，后端只是入库操作，不做上传文件操作,给用户端使用
	  *
	  **/
   @ResponseBody
   @RequestMapping("/imgClientApi/upload/saveWebImgInfoImg")
   public Object saveWebImgInfoImg(@RequestBody String arg,HttpServletRequest request) throws Exception {
       Map<String, Object> retMap = new HashMap<String, Object>();

       JSONObject jsonArg = null;
       try {
           jsonArg = JSON.parseObject(arg);
       } catch (Exception ex) {
           ex.printStackTrace();
           throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
       }

       JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
       if (null == jsonData) {
           // 前台必须传data节点，否则报错返回
           throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
       }

       Map<String, Object> mapIn = jsonData;
       logger.info("saveWebImgInfo :"+mapIn);

       // 操作信息校验
       Map<String, Object> chkVar = new HashMap<String, Object>();
       Map<String, Object> chkInfo = ToolUtil.typeCast(mapIn.get("oprInfo"));
       chkVar.put("opCode", "操作编码");
       chkVar.put("opType", "操作类型");
       chkVar.put("opNote", "操作备注");
       chkVar.put("equipId", "设备id");
       chkVar.put("equipFlag", "设备标志类型");
       ToolUtil.checkInputInfo("oprInfo", chkInfo, chkVar);
       chkInfo.put("updateTime", DateUtil.getSysDateA());
       chkInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
       chkInfo.put("uploadType", Constants.FILE_UPLOAD_TYPE_FOR_MANUAL);
       // 设备信息校验
       chkVar.clear();
       List<Object> fileList = ToolUtil.typeCast(mapIn.get("fileList"));
       chkVar.put("fileCreateTime", "文件创建时间");
       chkVar.put("fileModifyTime", "文件修改时间");
       chkVar.put("sourceFileName", "文件原来名称");
       chkVar.put("fileSize", "文件大小");
       chkVar.put("filePath", "文件保存阿里地址");

       ToolUtil.checkInputList("fileList", fileList, chkVar);
       // 校验文件扩展名
       for(int i=0;i<fileList.size();i++) {
       	//将Object 转成map
       	Map<String,Object> map = ToolUtil.typeCast(fileList.get(i));
       	map.put("fileSize", Long.parseLong((String)map.get("fileSize")));
       	ToolUtil.checkFileSuffix((String)map.get("sourceFileName"));
       	 int pointPos = ((String) map.get("filePath")).lastIndexOf(Constants.SLASH_STR);
            if (-1 != pointPos) {
               String substring = ((String) map.get("filePath")).substring(pointPos + 1);
               map.put("fileName", substring);
            }
            pointPos = ((String) map.get("sourceFileName")).lastIndexOf(Constants.dot);
            if (-1 != pointPos) {
           	 String substring = ((String) map.get("sourceFileName")).substring(pointPos + 1).toLowerCase();
                map.put("fileType", substring);
            }
       }

       // 患者基本信息校验
       chkVar.clear();
       chkInfo = ToolUtil.typeCast(mapIn.get("userInfo"));
       chkVar.put("userId", "患者id");
       chkVar.put("birthday", "出生日期");
       chkVar.put("gender", "性别");
       ToolUtil.checkInputInfo("userInfo", chkInfo, chkVar);
       Map<String, Object> sessionMap = new HashMap<String,Object>();
       sessionMap.put("tenantId", chkInfo.get("tenantId"));
       mapIn.put("sessionInfo", sessionMap);
       retMap = clientImgDealService.saveWebImgInfo(mapIn);

       return new ResultModel<Object>(retMap);
   }

}
